package com.fau.ss.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fau.ss.entity.MedicalAdmin;
import com.fau.ss.entity.MedicalKeyValue;
import com.fau.ss.entity.MedicalMediaInfo;
import com.fau.ss.entity.MedicalSsPurchase;
import com.fau.ss.service.IBuyFrequencyStaService;
import com.fau.ss.util.DateUtil;
import com.fau.ss.util.Page;
import com.fau.ss.util.ParamUtil;
import com.fau.ss.util.SystemConfig;
import com.sun.tools.jdi.LinkedHashMap;


@Service
@Transactional(readOnly = true)
public class BuyFrequencyStaService extends BaseService implements IBuyFrequencyStaService {

	@Override
	public Page findHabitsByPage(Map<String, Object> map, MedicalSsPurchase purchase, MedicalAdmin admin) {
		
		StringBuilder statusSql = new StringBuilder("from MedicalSsPurchase a where 1=1 and a.hospitalId = ? "); 
		StringBuilder countSql = new StringBuilder("select count(distinct a.customerId) from MedicalSsPurchase a where a.id in (select "
				+ "m.id from MedicalSsPurchase m where 1=1 and m.hospitalId = ? ) ");
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		Date startTime = null;
		Date endTime = null;
		if(StringUtils.isNotBlank(purchase.getStartTime()) && StringUtils.isNotBlank(purchase.getEndTime())) {
			startTime = DateUtil.getDate(purchase.getStartTime());
			endTime = DateUtil.getDate(purchase.getEndTime());
			statusSql.append("and a.ordersDate between ? and ? ");
			countSql.append("and a.ordersDate between ? and ? ");
			objectList.add(startTime);
			objectList.add(endTime);
		}
		
		statusSql.append("group by a.customerId order by count(distinct a.ordersId) desc");
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map, "pageIndex", 1), ParamUtil.getInteger(map, "pageSize", 20), map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalSsPurchase> list = new ArrayList<MedicalSsPurchase>();
		StringBuilder hql = new StringBuilder();
		List<Object> objects = new ArrayList<Object>();
		for(Object obj : page.getResult()){
			MedicalSsPurchase bean = (MedicalSsPurchase) obj;
			MedicalKeyValue kv = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), bean.getSex());
			bean.setSexValue(kv.getKeyValue());
			hql.append("select count(*) from MedicalSsPurchase a where a.id in (select id from MedicalSsPurchase group by ordersId) and a.customerId = ? ");
			objects.add(bean.getCustomerId());
			if(null != startTime && null != endTime){
				hql.append("and a.ordersDate between ? and ? ");
				objects.add(startTime);
				objects.add(endTime);
			}
			int countBuy = this.iBaseDao.getIntCount(hql.toString(), objects.toArray());
			bean.setCountBuy(countBuy);
			list.add(bean);
			hql.delete( 0, hql.length() );
			objects.clear();
		}
		return page;
	}

	@Override
	public Page findHabitsMedicineByPage(Map<String, Object> map, MedicalSsPurchase purchase, MedicalAdmin admin) {
		StringBuilder statusSql = new StringBuilder("from MedicalSsPurchase a where 1=1 and a.hospitalId = ? "); 
		StringBuilder countSql = new StringBuilder("select count(distinct a.customerId) from MedicalSsPurchase a where a.id in (select "
				+ "m.id from MedicalSsPurchase m where 1=1 and m.hospitalId = ? )");
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		Date startTime = null;
		Date endTime = null;
		if(StringUtils.isNotBlank(purchase.getStartTime()) && StringUtils.isNotBlank(purchase.getEndTime())) {
			startTime = DateUtil.getDate(purchase.getStartTime());
			endTime = DateUtil.getDate(purchase.getEndTime());
			statusSql.append(" and a.ordersDate between ? and ? ");
			countSql.append(" and a.ordersDate between ? and ? ");
			objectList.add(startTime);
			objectList.add(endTime);
		}
		
		if(StringUtils.isNotBlank(purchase.getMedicineSortId())) {
			statusSql.append(" and a.medicineSortId = ? ");
			countSql.append(" and a.medicineSortId = ? ");
			objectList.add(purchase.getMedicineSortId());
		}
		
		statusSql.append(" group by a.customerId order by count(a.ordersId) desc");
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map, "pageIndex", 1), ParamUtil.getInteger(map, "pageSize", 20), map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalSsPurchase> list = new ArrayList<MedicalSsPurchase>();
		StringBuilder hql = new StringBuilder();
		List<Object> objects = new ArrayList<Object>();
		for(Object obj : page.getResult()){
			MedicalSsPurchase bean = (MedicalSsPurchase) obj;
			MedicalKeyValue kv = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), bean.getSex());
			bean.setSexValue(kv.getKeyValue());
			hql.append("select count(distinct a.ordersId) from MedicalSsPurchase a where a.customerId = ? ");
			objects.add(bean.getCustomerId());
			
			if(null != startTime && null != endTime){
				hql.append(" and a.ordersDate between ? and ?" );
				objects.add(startTime);
				objects.add(endTime);
			}
			if(StringUtils.isNotBlank(purchase.getMedicineSortId())) {
				hql.append(" and a.medicineSortId = ? ");
				objects.add(purchase.getMedicineSortId());
			}
			int countBuy = this.iBaseDao.getIntCount(hql.toString(), objects.toArray());
			bean.setCountBuy(countBuy);
			list.add(bean);
			hql.delete( 0, hql.length() );
			objects.clear();
		}
		return page;
	}
	
	@Override
	public List<String> countByAge(MedicalSsPurchase purchase, MedicalAdmin admin) {
		List<String> list = new ArrayList<String>(5);
		Date startTime = null;
		Date endTime = null;
		if(StringUtils.isNotBlank(purchase.getStartTime()) && StringUtils.isNotBlank(purchase.getEndTime())){
			startTime = DateUtil.getDate(purchase.getStartTime());
			endTime = DateUtil.getDate(purchase.getEndTime());
		}
		int count1 = 0;
		int count2 = 0;
		int count3 = 0;
		int count4 = 0;
		int count5 = 0;
		StringBuilder hql = new StringBuilder("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ? and a.age between ? and ? ");
		if(null != startTime && null != endTime){
			hql.append("and a.ordersDate between ? and ? ");
			count1 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 20, 30, startTime, endTime);
			count2 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 31, 40, startTime, endTime);
			count3 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 41, 50, startTime, endTime);
			count4 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 51, 60, startTime, endTime);
			count5 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ? and"
					+ " a.age > ? and a.ordersDate between ? and ? ", admin.getEnterpriseId(), 60, startTime, endTime);
		}else{
			count1 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 20, 30);
			count2 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 31, 40);
			count3 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 41, 50);
			count4 = this.iBaseDao.getIntCount(hql.toString(), admin.getEnterpriseId(), 51, 60);
			count5 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ? and a.age > ? ", admin.getEnterpriseId(), 60);
		}
		list.add(String.valueOf(count1));
		list.add(String.valueOf(count2));
		list.add(String.valueOf(count3));
		list.add(String.valueOf(count4));
		list.add(String.valueOf(count5));
		return list;
	}

	@Override
	public List<String> countByYear(MedicalSsPurchase purchase, MedicalAdmin admin) {
		List<String> list = new ArrayList<String>();
		int count = 0;
		if(null != purchase.getCountBuy()){
			for(int i=1;i<13;i++){
				count = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ?"
						+ " and YEAR(a.ordersDate) = ? AND MONTH(a.ordersDate) = ? ", admin.getEnterpriseId(), purchase.getCountBuy(), i);
				list.add(String.valueOf(count));
			}
		}else{
			for(int i=1;i<13;i++){
				count = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ?"
						+" and YEAR(a.ordersDate) = YEAR(CURDATE()) AND MONTH(a.ordersDate) = ? ", admin.getEnterpriseId(), i);
				list.add(String.valueOf(count));
			}
		}
		return list;
	}

	@Override
	public List<String> countByMonth(MedicalSsPurchase purchase, MedicalAdmin admin) {
		List<String> list = new ArrayList<String>(3);
		int count1 = 0;
		int count2 = 0;
		int count3 = 0;
		if(StringUtils.isNotBlank(purchase.getStartTime())){
			count1 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 AND a.hospitalId = ? AND DATE_FORMAT(a.ordersDate,'%Y—%m') = ? AND DAY(a.ordersDate) BETWEEN ? AND ? ", admin.getEnterpriseId(), purchase.getStartTime(), 1, 10);
			count2 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 AND a.hospitalId = ? AND DATE_FORMAT(a.ordersDate,'%Y—%m') = ? AND DAY(a.ordersDate) BETWEEN ? AND ? ", admin.getEnterpriseId(), purchase.getStartTime(), 11, 20);
			count3 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 AND a.hospitalId = ? AND DATE_FORMAT(a.ordersDate,'%Y—%m') = ? AND DAY(a.ordersDate) > ? ", admin.getEnterpriseId(), purchase.getCountBuy(), 20);
		}else{
			count1 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 AND a.hospitalId = ? AND MONTH(a.ordersDate) = (MONTH(CURDATE())) AND DAY(a.ordersDate) BETWEEN ? AND ? ", admin.getEnterpriseId(), 1, 10);
			count2 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 AND a.hospitalId = ? AND MONTH(a.ordersDate) = (MONTH(CURDATE())) AND DAY(a.ordersDate) BETWEEN ? AND ? ", admin.getEnterpriseId(), 11, 20);
			count3 = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 AND a.hospitalId = ? AND MONTH(a.ordersDate) = (MONTH(CURDATE())) AND DAY(a.ordersDate) > ? ", admin.getEnterpriseId(), 20);
		}
		list.add(String.valueOf(count1));
		list.add(String.valueOf(count2));
		list.add(String.valueOf(count3));
		return list;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> countByLevel(MedicalSsPurchase purchase, MedicalAdmin admin) {
		Map<String, Object> map = new LinkedHashMap();
		
		List<MedicalKeyValue> keyValList = this.iBaseDao.findValueByType(admin.getEnterpriseId(), SystemConfig.CM_SYSTEM_TYPE, SystemConfig.LEVEL_TYPE);
		Date startTime = null;
		Date endTime = null;
		if(StringUtils.isNotBlank(purchase.getStartTime()) && StringUtils.isNotBlank(purchase.getEndTime())){
			startTime = DateUtil.getDate(purchase.getStartTime());
			endTime = DateUtil.getDate(purchase.getEndTime());
			for(MedicalKeyValue callKeyVal : keyValList){
				int count = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ? and a.level = ? and a.ordersDate between ? and ? ", admin.getEnterpriseId(), callKeyVal.getKeyName(), startTime, endTime);
				map.put(callKeyVal.getKeyValue(), count);
			}
		}else{
			for(MedicalKeyValue callKeyVal : keyValList){
				int count = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ? and a.level = ? ", admin.getEnterpriseId(), callKeyVal.getKeyName());
				map.put(callKeyVal.getKeyValue(), count);
			}
		}
		return map;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> countByArea(MedicalSsPurchase purchase, MedicalAdmin admin) {
		Map<String, Object> map = new LinkedHashMap();
		Date startTime = null;
		Date endTime = null;
		List<MedicalMediaInfo> list = this.iBaseDao.getBySql("from MedicalMediaInfo m where 1=1 and m.eid = ? group by m.cityId ", null, admin.getEnterpriseId());
		if(StringUtils.isNotBlank(purchase.getStartTime()) && StringUtils.isNotBlank(purchase.getEndTime())){
			startTime = DateUtil.getDate(purchase.getStartTime());
			endTime = DateUtil.getDate(purchase.getEndTime());
			for(MedicalMediaInfo bean : list){
				int count = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ? and a.cityId = ? and a.ordersDate between ? and ? ", admin.getEnterpriseId(), bean.getCityId(), startTime, endTime);
				String address = bean.getAddress().substring(bean.getAddress().indexOf("-")+1, bean.getAddress().lastIndexOf("-"));
				map.put(address, count);
			}
		}else{
			for(MedicalMediaInfo bean : list){
				int count = this.iBaseDao.getIntCount("select count(distinct a.customerId) from MedicalSsPurchase a where 1=1 and a.hospitalId = ? and a.cityId = ? ", admin.getEnterpriseId(), bean.getCityId());
				String address = bean.getAddress().substring(bean.getAddress().indexOf("-")+1, bean.getAddress().lastIndexOf("-"));
				map.put(address, count);
			}
		}
		return map;
	}

}
